<script setup lang="ts">
import type { VbenFormProps } from '@vben/common-ui';
import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';

import type { RowType } from './sysUser.data';

import { createVNode, onMounted, reactive, ref } from 'vue';

import { AccessControl } from '@vben/access';
import { ColPage, ColVerticalPage, useVbenModal } from '@vben/common-ui';
import { AntDesignOutLined, IconifyIcon } from '@vben/icons';

import { message, Modal } from 'ant-design-vue';

import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { querySelectTreeTableApi } from '#/api';
import {
  sysUserDelApi,
  sysUserDeleteBatchApi,
  sysUserQueryByIdApi,
  sysUserQueryPageListApi,
  sysUserResetPassWordApi,
} from '#/api/system/sysUser';
import { SparkDescriptions } from '#/components';
import { getAllNodeKeys, queryDictOptionsApi, useDictionaries } from '#/utils';

import SysUserFormModal from './modules/SysUserFormModal.vue';
import { DetailsColumns } from './sysUser.data.ts';

const { translateValue } = useDictionaries(['sex', 'status']);

const allKey = '9999';
const typeSearchContent = ref('');
const expandedKeys = ref<string[]>([]);
const selectedKeys = ref<string[]>([allKey]);
const typeData = reactive([]);
const detailsRef = ref();

onMounted(async () => {
  await loadTypeData();
});

const formOptions: VbenFormProps = {
  layout: 'horizontal',
  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
  showCollapseButton: false,
  actionButtonsReverse: false,
  showDefaultActions: true,
  submitOnChange: false,
  submitOnEnter: false,
  commonConfig: {
    colon: true,
    labelWidth: 80,
  },
  schema: [
    {
      component: 'Input',
      label: '用户昵称',
      fieldName: 'nickname',
      componentProps: {
        placeholder: '请输入用户昵称',
      },
    },
    {
      component: 'Input',
      label: '用户账号',
      fieldName: 'username',
      componentProps: {
        placeholder: '请输入用户账号',
      },
    },
    {
      component: 'Input',
      label: '邮箱',
      fieldName: 'email',
      componentProps: {
        placeholder: '请输入邮箱',
      },
    },
    {
      component: 'Input',
      label: '手机号',
      fieldName: 'phone',
      componentProps: {
        placeholder: '请输入手机号',
      },
    },
    {
      component: 'ApiSelect',
      label: '状态',
      fieldName: 'status',
      componentProps: {
        placeholder: '请选择状态',
        allowClear: true,
        showSearch: true,
        afterFetch: (data) => {
          return data.map((item: any) => ({
            label: item.itemText,
            value: Number.parseInt(item.itemVal),
          }));
        },
        api: queryDictOptionsApi,
        params: {
          dictCode: 'status',
        },
      },
    },
  ],
  // 自定义表单重置方法
  handleReset: () => {
    // eslint-disable-next-line no-use-before-define
    gridApi.formApi.resetForm();
    // eslint-disable-next-line no-use-before-define
    gridApi.query();
  },
  // 自定义表单提交方法
  handleSubmit: (values) => {
    values = {
      ...values,
      dept_id: selectedKeys.value[0] ?? '',
    };
    // eslint-disable-next-line no-use-before-define
    gridApi.query(values);
  },
};

const gridOptions: VxeTableGridOptions<RowType> = {
  height: 'auto',
  toolbarConfig: {
    slots: {
      buttons: 'toolbar-buttons',
    },
  },
  columns: [
    { type: 'checkbox', width: 50, fixed: 'left', align: 'center' },
    { title: '序号', type: 'seq', width: 50, fixed: 'left', align: 'center' },
    {
      title: '头像',
      field: 'avatar',
      align: 'center',
      cellRender: {
        name: 'CellImage',
      },
      minWidth: 60,
    },
    {
      title: '用户昵称',
      field: 'nickname',
      align: 'center',
      minWidth: 100,
    },
    {
      title: '用户账号',
      field: 'username',
      align: 'center',
      minWidth: 100,
    },
    {
      title: '邮箱',
      field: 'email',
      align: 'center',
      minWidth: 130,
    },
    {
      title: '手机号',
      field: 'phone',
      align: 'center',
      minWidth: 100,
    },
    // {
    //   title: '性别',
    //   field: 'sex',
    //   align: 'center',
    //   cellRender: {
    //     name: 'CellDict',
    //     attrs: {
    //       dictCode: 'sex',
    //       translateValue,
    //     },
    //   },
    // },
    {
      title: '状态',
      field: 'status',
      align: 'center',
      cellRender: {
        name: 'CellDict',
        attrs: {
          dictCode: 'status',
          translateValue,
        },
      },
      minWidth: 80,
    },
    {
      title: '备注',
      field: 'remark',
      align: 'center',
      minWidth: 100,
    },
    {
      title: '部门',
      field: 'deptId_dictText',
      align: 'center',
      minWidth: 100,
    },
    {
      title: '主键',
      field: 'id',
      align: 'center',
      visible: false,
    },
    {
      title: '创建人',
      field: 'createBy',
      align: 'center',
      visible: false,
    },
    {
      title: '创建时间',
      field: 'createTime',
      align: 'center',
      minWidth: 160,
    },
    {
      title: '更新人',
      field: 'updateBy',
      align: 'center',
      visible: false,
    },
    {
      title: '更新时间',
      field: 'updateTime',
      align: 'center',
      visible: false,
    },
    {
      title: '操作',
      field: 'action',
      align: 'center',
      minWidth: 210,
      fixed: 'right',
      slots: {
        default: 'action',
      },
    },
  ],
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues) => {
        return await sysUserQueryPageListApi({
          pageNo: page.currentPage,
          pageSize: page.pageSize,
          ...formValues,
        });
      },
    },
  },
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
const [FromModal, formModalApi] = useVbenModal({
  connectedComponent: SysUserFormModal,
  onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      gridApi.query();
    }
  },
});
async function handlerAdd() {
  formModalApi.setData({ id: undefined });
  formModalApi.open();
}
async function handlerEdit(row) {
  formModalApi.setData({ id: row.id });
  formModalApi.open();
}
async function handlerDel(row) {
  const msg = await sysUserDelApi(row.id);
  message.success(msg);
  await gridApi.query();
}
async function handlerBatchDel() {
  const checkboxRecords = gridApi.grid.getCheckboxRecords();
  if (checkboxRecords.length === 0) {
    message.warn('至少选中一行');
  } else {
    const idArray = checkboxRecords.map((record) => record.id);
    const ids = idArray.join(',');
    Modal.confirm({
      title: '系统提示?',
      content: createVNode(
        'div',
        { style: 'color:red;' },
        '确认删除所选中行吗?',
      ),
      onOk() {
        sysUserDeleteBatchApi(ids).then(() => {
          message.success('删除成功');
          gridApi.query();
        });
      },
      class: 'test',
    });
  }
}

async function loadTypeData() {
  const data = await querySelectTreeTableApi({
    tableName: 'sys_dept',
    labelField: 'dept_name',
    valueField: 'id',
    sqlSelect: typeSearchContent.value
      ? `del_flag = 0 and dept_name LIKE CONCAT('%','${typeSearchContent.value}','%')`
      : 'del_flag = 0',
  });
  typeData.splice(0, typeData.length, ...data);
}
function handlerType(type) {
  const allKeys = getAllNodeKeys(typeData);
  type === 1 ? (expandedKeys.value = []) : (expandedKeys.value = allKeys);
}
async function handleTypeTree(keys) {
  selectedKeys.value[0] = keys[0];
  await gridApi.formApi.resetForm();
  await gridApi.query({ deptId: selectedKeys.value[0] });
}
async function handlerResetPass() {
  Modal.confirm({
    title: '系统提示?',
    content: createVNode(
      'div',
      { style: 'color:red;' },
      '密码将重置为：spark@123',
    ),
    async onOk() {
      const msg = await sysUserResetPassWordApi();
      message.success(msg);
    },
    class: 'test',
  });
}
async function handlerDetails(row) {
  detailsRef.value.open({ id: row.id }, DetailsColumns);
}
</script>

<template>
  <ColPage
    auto-content-height
    v-bind="{
      resizable: true,
      splitLine: true,
      splitHandle: true,
      leftWidth: 20,
      leftMinWidth: 20,
      leftMaxWidth: 20,
      leftCollapsedWidth: 3,
      leftCollapsible: true,
      rightWidth: 80,
    }"
  >
    <FromModal class="w-[50%]" />
    <SparkDescriptions
      class="w-[60%]"
      title="用户详情"
      ref="detailsRef"
      :api="sysUserQueryByIdApi"
    />
    <template #left="{ isCollapsed, expand }">
      <div v-if="isCollapsed" @click="expand">
        <a-tooltip title="点击展开左侧">
          <a-button shape="circle" type="primary">
            <template #icon>
              <IconifyIcon class="text-2xl" icon="bi:arrow-right" />
            </template>
          </a-button>
        </a-tooltip>
      </div>
      <div
        v-else
        class="border-border bg-card mr-2 h-full rounded-[var(--radius)] border p-2"
      >
        <ColVerticalPage>
          <template #header>
            <div class="flex items-center">
              <div class="w-20">组织机构</div>
              <div>
                <a-input-search
                  v-model:value="typeSearchContent"
                  placeholder="请输入组织机构"
                  enter-button
                  allow-clear
                  @search="loadTypeData"
                  size="small"
                />
              </div>
              <a-dropdown class="w-8">
                <AntDesignOutLined class="size-4" />
                <template #overlay>
                  <a-menu>
                    <a-menu-item @click="handlerType(0)">
                      展开全部
                    </a-menu-item>
                    <a-menu-item @click="handlerType(1)">
                      折叠全部
                    </a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
            </div>
          </template>
          <a-tree
            :show-line="true"
            :tree-data="typeData"
            :field-names="{ title: 'name', key: 'id' }"
            @select="handleTypeTree"
            v-model:expanded-keys="expandedKeys"
            v-model:selected-keys="selectedKeys"
          />
        </ColVerticalPage>
      </div>
    </template>
    <Grid class="ml-2">
      <template #toolbar-buttons>
        <a-button
          v-access:code="'sys:user:add'"
          type="primary"
          class="mr-2"
          @click="handlerAdd()"
        >
          新增
        </a-button>
      </template>
      <template #toolbar-tools>
        <a-button
          v-access:code="'sys:user:batchDel'"
          type="primary"
          danger
          @click="handlerBatchDel()"
        >
          批量删除
        </a-button>
      </template>
      <template #action="{ row }">
        <a-button
          v-access:code="'sys:user:edit'"
          v-if="row.username !== 'super'"
          type="link"
          size="small"
          @click="handlerEdit(row)"
        >
          编辑
        </a-button>
        <a-popconfirm
          cancel-text="再想想"
          title="您确定要删除吗?"
          @confirm="handlerDel(row)"
        >
          <a-button
            v-if="row.username !== 'super'"
            type="link"
            v-access:code="'sys:user:del'"
            danger
            size="small"
          >
            删除
          </a-button>
        </a-popconfirm>
        <a-dropdown>
          <template #overlay>
            <a-menu>
              <AccessControl :codes="['sys:user:resetPass']" type="code">
                <a-menu-item
                  v-if="row.username !== 'super'"
                  key="1"
                  @click="handlerResetPass()"
                >
                  重置密码
                </a-menu-item>
              </AccessControl>
              <AccessControl :codes="['sys:user:details']" type="code">
                <a-menu-item key="2" @click="handlerDetails(row)">
                  用户详情
                </a-menu-item>
              </AccessControl>
            </a-menu>
          </template>
          <a-button
            v-access:code="'sys:user:more'"
            size="small"
            type="link"
            @click.prevent
          >
            更多
            <AntDesignOutLined />
          </a-button>
        </a-dropdown>
      </template>
    </Grid>
  </ColPage>
</template>
